package com.mmall.concurrency.controller;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.mmall.concurrency.task.IfaasSerachTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author:LiuWei
 * @Description:
 * @Date: Created in 16:52 2019/7/3
 * @Modified By:
 */
@RestController
@Slf4j
public class TimeOutController {
    private static  ThreadFactory threadFactory = new ThreadFactoryBuilder()
            .setNameFormat("bodyDataProcess-process-%d").build();
    private static LinkedBlockingQueue<Runnable> linkedBlockingQueue = new LinkedBlockingQueue<Runnable>(1000);
    private static ExecutorService singleThrealPool = new ThreadPoolExecutor(2, 2,
            0L, TimeUnit.MILLISECONDS,linkedBlockingQueue,threadFactory);
    private static AtomicInteger userNum = new AtomicInteger(0);
    //1、10个请求，每个请求需要的时间是10s以内
    //2、service中一个方法是能同时处理2个请求，每个请求处理的时间是3s，也就是9s能够6个请求
    //3、最后1s则会导致2个请求超时，同时20个请求未进行service方法处理也超时。总之6个请求正常，4个请求超时，10s之内返回，不影响后面的请求
    @GetMapping("timeout")
    public String timeOutReqDemo(HttpServletRequest request) {
        request.setAttribute("requestTime",new Date());
        int num = userNum.get();
        userNum.incrementAndGet();
        log.info("request start user-{}",num);
        request.setAttribute("userNum",num);

        IfaasSerachTask ifaasSerachTask = new IfaasSerachTask(request);

        Future<?> submit = singleThrealPool.submit(ifaasSerachTask);
        try {
            Boolean flag = (Boolean)submit.get();
            log.info("linkedBlockingQueue size {}",linkedBlockingQueue.size());
            if(flag){
                return "success";
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return "fail";

    }
}
